home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
Updates
/
Datatypes
/
RGFX-DT
/
Source
/
dt2rgfx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-14
|
8KB
|
317 lines
#include <clib/alib_protos.h>
#include <pragma/cybergraphics_lib.h>
#include <pragma/datatypes_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/iffparse_lib.h>
#include <pragma/xpkmaster_lib.h>
#include <datatypes/pictureclass.h>
#include <exec/memory.h>
#include <libraries/rgfx.h>
#include <stdlib.h>
static char ver[]="$VER:DT2RGFX 43.11 (08.10.99) © 1997-99 by Achim Stegemann\n";
static char *ifferrmsg[]=
{
0,
0,
0,
"No valid scope for property",
"Internal memory alloc failed",
"Stream read error",
"Stream write error",
"Stream seek error",
"Data in file is corrupt",
"IFF syntax error",
"Not an IFF file",
"No call-back hook provided"
};
static long ifferr,xpkerr,memerr,xpkmode=100;
static char xpkerrmsg[XPKERRMSGSIZE];
struct
{
char *from;
char *to;
char *xpk;
long *xpkmode;
char *password;
long verbose;
} args;
Library *CyberGfxBase,*XpkBase;
static void Ende()
{
CloseLibrary(CyberGfxBase);
CloseLibrary(XpkBase);
}
static void Init()
{
CyberGfxBase=OpenLibrary("cybergraphics.library",40);
if(!(XpkBase=OpenLibrary("xpkmaster.library",5)))
{
PutStr("DT2RGFX requires xpkmaster.library V5 or better\n");
exit(20);
}
}
static BOOL PutRGHD(IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
if(!(ifferr=PushChunk(iff,0,ID_RGHD,sizeof(RGHD))))
{
if((ifferr=WriteChunkRecords(iff,rh,sizeof(RGHD),1))==1)
{
if(!(ifferr=PopChunk(iff))) ret=1;
}
}
return ret;
}
static BOOL PutRCOL(Object *obj,IFFHandle *iff)
{
BOOL ret=0;
if(!(ifferr=PushChunk(iff,0,ID_RCOL,sizeof(RCOL))))
{
RCOL *rc;
if(rc=(RCOL *)AllocVec(sizeof(RCOL),MEMF_CLEAR))
{
ULONG i,n,*cr;
GetDTAttrs(obj,PDTA_NumColors,&n,PDTA_CRegs,&cr,TAG_END);
for(i=0;i<n;i++)
{
UWORD j;
for(j=0;j<3;j++) rc->rcol_Colors[i][j]=*(cr++)>>24;
}
if((ifferr=WriteChunkRecords(iff,rc,sizeof(RCOL),1))==1)
{
if(!(ifferr=PopChunk(iff))) ret=1;
}
FreeVec(rc);
}
else memerr=1;
}
return ret;
}
static BOOL PutRSCM(Object *obj,IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
if(!(ifferr=PushChunk(iff,0,ID_RSCM,sizeof(RSCM))))
{
ULONG mode;
RSCM rs={INVALID_ID,INVALID_ID,INVALID_ID};
GetDTAttrs(obj,PDTA_ModeID,&mode,TAG_END);
if(CyberGfxBase&&IsCyberModeID(mode))
{
rs.rscm_CGfx=mode;
if(rh->rgfx_Depth<=8) rs.rscm_AGA=BestModeID(
BIDTAG_NominalWidth,rh->rgfx_PageWidth,BIDTAG_NominalHeight,rh->rgfx_PageHeight,
BIDTAG_DesiredWidth,rh->rgfx_Width,BIDTAG_DesiredHeight,rh->rgfx_Height,
BIDTAG_Depth,rh->rgfx_Depth,BIDTAG_MonitorID,DEFAULT_MONITOR_ID,
BIDTAG_DIPFMustNotHave,DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM|DIPF_IS_EXTRAHALFBRITE,TAG_END);
}
else
{
rs.rscm_AGA=mode;
if(!(mode&(HAM_KEY|EXTRAHALFBRITE_KEY|LORESDPF_KEY)))
{
if(CyberGfxBase) rs.rscm_CGfx=BestCModeIDTags(CYBRBIDTG_NominalWidth,rh->rgfx_Width,CYBRBIDTG_NominalHeight,rh->rgfx_Height,CYBRBIDTG_Depth,rh->rgfx_Depth,TAG_END);
}
}
if((ifferr=WriteChunkRecords(iff,&rs,sizeof(RSCM),1))==1)
{
if(!(ifferr=PopChunk(iff))) ret=1;
}
}
return ret;
}
static BOOL WriteChunky_XPK(Object *obj,IFFHandle *iff,RGHD *rh,BitMap *bm)
{
BOOL ret=0;
ULONG len=rh->rgfx_Width*rh->rgfx_Height;
UBYTE *mem;
if(mem=(UBYTE *)AllocVec(len,0))
{
UBYTE *pix;
if(pix=(UBYTE *)AllocVec(((rh->rgfx_Width+16)>>4)<<4,0))
{
BitMap *tbm;
if(tbm=AllocBitMap(rh->rgfx_Width,1,rh->rgfx_Depth,0,bm))
{
ULONG y,xpklen,outlen;
UBYTE *xpk=mem;
RastPort rp,trp;
InitRastPort(&rp);
InitRastPort(&trp);
rp.BitMap=bm;
trp.BitMap=tbm;
for(y=0;y<rh->rgfx_Height;y++,xpk+=rh->rgfx_Width)
{
ReadPixelLine8(&rp,0,y,rh->rgfx_Width,pix,&trp);
CopyMem(pix,xpk,rh->rgfx_Width);
}
if(!(xpkerr=XpkPackTags(XPK_InBuf,mem,XPK_InLen,len,XPK_GetOutBuf,&xpk,XPK_GetOutBufLen,&xpklen,XPK_GetOutLen,&outlen,XPK_PackMethod,args.xpk,XPK_PackMode,xpkmode,XPK_Password,args.password,XPK_GetError,xpkerrmsg,TAG_END)))
{
if((ifferr=WriteChunkRecords(iff,xpk,outlen,1))==1) ret=1;
FreeMem(xpk,xpklen);
}
FreeBitMap(tbm);
}
else memerr=1;
FreeVec(pix);
}
else memerr=1;
FreeVec(mem);
}
else memerr=1;
return ret;
}
static BOOL Write24_XPK(Object *obj,IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
UBYTE *pix;
ULONG len=rh->rgfx_BytesPerLine*rh->rgfx_Height;
if(pix=(UBYTE *)AllocVec(len,0))
{
ULONG xpklen,outlen;
UBYTE *xpk;
DoMethod(obj,PDTM_READPIXELARRAY,pix,RECTFMT_RGB,rh->rgfx_BytesPerLine,0,0,rh->rgfx_Width,rh->rgfx_Height);
if(!(xpkerr=XpkPackTags(XPK_InBuf,pix,XPK_InLen,len,XPK_GetOutBuf,&xpk,XPK_GetOutBufLen,&xpklen,XPK_GetOutLen,&outlen,XPK_PackMethod,args.xpk,XPK_PackMode,xpkmode,XPK_Password,args.password,XPK_GetError,xpkerrmsg,TAG_END)))
{
if((ifferr=WriteChunkRecords(iff,xpk,outlen,1))==1) ret=1;
FreeMem(xpk,xpklen);
}
FreeVec(pix);
}
else memerr=1;
return ret;
}
static BOOL PutBODY(Object *obj,IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
if(!(ifferr=PushChunk(iff,0,ID_RBOD,IFFSIZE_UNKNOWN)))
{
BOOL wok=0;
BitMap *bm;
GetDTAttrs(obj,PDTA_BitMap,&bm,TAG_END);
if(args.verbose) PutStr("Writing IFF-RGFX file ...\n");
if(rh->rgfx_Depth>8) wok=Write24_XPK(obj,iff,rh);
else wok=WriteChunky_XPK(obj,iff,rh,bm);
if(wok)
{
if(!(ifferr=PopChunk(iff))) ret=1;
}
}
return ret;
}
void main()
{
ULONG ret=10;
RDArgs *rd;
atexit(Ende);
Init();
if(rd=ReadArgs("FROM/A,TO/A,XPK/A/K,MODE/K/N,PW=PASSWORD/K,VERBOSE/S",(long *)&args,0))
{
BOOL ok=0;
Object *obj;
if(args.verbose) Printf("Loading %s ...\n",args.from);
if(args.xpkmode)
{
xpkmode=*args.xpkmode;
if(xpkmode<0) xpkmode=0;
else if(xpkmode>100) xpkmode=100;
}
if(obj=NewDTObject(args.from,DTA_GroupID,GID_PICTURE,PDTA_Remap,0,PDTA_DestMode,PMODE_V43,TAG_END))
{
if(DoDTMethod(obj,0,0,DTM_PROCLAYOUT,0,1))
{
IFFHandle *iff;
if(iff=AllocIFF())
{
if(iff->iff_Stream=Open(args.to,MODE_NEWFILE))
{
InitIFFasDOS(iff);
if(!(ifferr=OpenIFF(iff,IFFF_WRITE)))
{
if(!(ifferr=PushChunk(iff,ID_RGFX,ID_FORM,IFFSIZE_UNKNOWN)))
{
BitMapHeader *bh;
RGHD rh;
GetDTAttrs(obj,PDTA_BitMapHeader,&bh,TAG_END);
rh.rgfx_LeftEdge=bh->bmh_Left;
rh.rgfx_TopEdge=bh->bmh_Top;
rh.rgfx_Width=bh->bmh_Width;
rh.rgfx_Height=bh->bmh_Height;
rh.rgfx_PageWidth=bh->bmh_PageWidth?bh->bmh_PageWidth:rh.rgfx_Width;
rh.rgfx_PageHeight=bh->bmh_PageHeight?bh->bmh_PageHeight:rh.rgfx_Height;
rh.rgfx_Depth=bh->bmh_Depth;
if(args.verbose) Printf("Image size: %lu*%lu*%lu\n",rh.rgfx_Width,rh.rgfx_Height,rh.rgfx_Depth);
if(rh.rgfx_Depth<=8)
{
rh.rgfx_PixelBits=8;
rh.rgfx_BytesPerLine=rh.rgfx_Width;
rh.rgfx_BitMapType=RMBT_BYTECHUNKY8;
if(args.verbose) Printf("Saving in Chunky mode.\n");
}
else
{
rh.rgfx_PixelBits=24;
rh.rgfx_BytesPerLine=rh.rgfx_Width*3;
rh.rgfx_BitMapType=RMBT_3BYTERGB24;
if(args.verbose) Printf("Saving in RGB24 mode.\n");
}
rh.rgfx_Compression=RCMT_XPK;
if(args.verbose) Printf("Using Xpk packer %s.\n",args.xpk);
rh.rgfx_XAspect=bh->bmh_XAspect;
rh.rgfx_YAspect=bh->bmh_YAspect;
if(PutRGHD(iff,&rh))
{
if(bh->bmh_Depth>8||PutRCOL(obj,iff))
{
if(PutRSCM(obj,iff,&rh)) ok=PutBODY(obj,iff,&rh);
}
}
if(ok)
{
if(ifferr=PopChunk(iff)) ok=0;
}
}
CloseIFF(iff);
}
Close(iff->iff_Stream);
if(ifferr<-2) Printf("IFF error: %s\n",ifferrmsg[-ifferr]);
if(xpkerr) Printf("Xpk error: %s\n",xpkerrmsg);
if(memerr) PutStr("Out of memory.\n");
if(!ok) DeleteFile(args.to);
else
{
if(args.verbose) PutStr("Conversion finished.\n");
SetProtection(args.to,FIBF_EXECUTE);
ret=0;
}
}
FreeIFF(iff);
}
else PutStr("AllocIFF failed.\n");
}
else PutStr("DTObject Layout failed.\n");
DisposeDTObject(obj);
}
else Printf("Loading of DTObject %s failed.\n",args.from);
FreeArgs(rd);
}
if(IoErr()) PrintFault(IoErr(),"DOS error");
exit(ret);
}